home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1996 July / Macworld (1996-07).dmg / For your System Folder / Sound Manager 3.2a2 / Sound 3.2 release notes next >
Text File  |  1995-11-24  |  16KB  |  287 lines

  1. Sound Manager 3.2 New Features
  2. November 24, 1995
  3.  
  4. Sound Manager 3.2 contains some new routines for determining sound formats and converting between sound formats. This document describes the application programming interface to these new features and the bug fixes.
  5.  
  6. The information described here is confidential and subject to change. Do not share this information with other parties.
  7.  
  8. Determining Sound Hardware Settings
  9.  
  10. New Sound Manager routines: GetSoundOutputInfo() and SetSoundOutputInfo().
  11.  
  12. Two routines have been added to get and set information about the sound environment: GetSoundOutputInfo() and SetSoundOutputInfo. Both routines use a selector-based interface similar to the SPBGetDeviceInfo/SPBSetDeviceInfo routines found in the Sound Input Manager, and in fact they use the same selectors.
  13.  
  14. GetSoundOutputInfo() and SetSoundOutputInfo() operate directly on a sound output device, and can be used to retrieve and change information about the hardware settings. These routines should be used instead of attempting to communicate directly with sound output components. Setting the output device parameter to nil causes the default output device to be used. These calls are similar to GetSndInfo() and SetSndInfo() but do not require an opened sound channel.
  15.  
  16. pascal OSErr GetSoundOutputInfo(Component outputDevice, OSType selector, void *infoPtr);
  17.  
  18. pascal OSErr SetSoundOutputInfo(Component outputDevice, OSType selector, const void *infoPtr);
  19.  
  20. These new calls are only available with Sound Manager version 3.1 or later. Check for this by calling SndSoundManagerVersion() for the installed version.
  21.  
  22. For example, to determine the sampling rate of the sound hardware on the default output device, you could use this code:
  23.  
  24. OSErr GetCurrentSampleRate(UnsignedFixed *sampleRate)
  25. {
  26.     OSErr           err;
  27.  
  28.     err = GetSoundOutputInfo(nil, siSampleRate, sampleRate);
  29.     return (err);
  30. }
  31.  
  32. Determining Sound Formats
  33.  
  34. pascal OSErr ParseAIFFHeader(short fRefNum, SoundComponentData *sndInfo,
  35.                        unsigned long *numFrames, unsigned long *dataOffset)
  36.  
  37. ParseAIFFHeader returns information describing the audio data in the given AIFF file. The fRefNum parameter specifies the open AIFF file to use. The sndInfo parameter is a SoundComponentData structure that returns the following information about the format of the sound in the AIFF file:
  38.  
  39.     flags           - always returns 0
  40.     format          - the sound format (i.e. 'raw ', 'twos', 'MAC3', etc.)
  41.     numChannels     - the number of channels  (i.e. 1 = mono, 2 = stereo)
  42.     sampleSize      - the sample size (i.e. 8 = 8-bit, 16 = 16-bit)
  43.     sampleRate      - the sampling rate (in samples/second)
  44.     sampleCount     - the number of audio samples in the file
  45.     buffer          - always returns 0
  46.     reserved        - always returns 0
  47.  
  48. The numFrames parameter returns the number of frames of audio data in the file, and the dataOffset parameter returns the byte offset of the first audio sample in the file.
  49.  
  50. Errors:
  51.     siInvalidCompression    - compression type not supported
  52.     badFileFormat           - file does not contain valid AIFF data
  53.  
  54. pascal OSErr ParseSndHeader(SndListHandle sndHandle, SoundComponentData *sndInfo,
  55.                        unsigned long *numFrames, unsigned long *dataOffset)
  56.  
  57. ParseSndHeader returns information describing the audio data in the given 'snd ' resource handle. The sndHandle parameter specifies the sound handle to use. The sndInfo parameter is a SoundComponentData structure that returns the following information about the format of the sound in the handle:
  58.  
  59.     flags           - always returns 0
  60.     format          - the sound format (i.e. 'raw ', 'twos', 'MAC3', etc.)
  61.     numChannels     - the number of channels  (i.e. 1 = mono, 2 = stereo)
  62.     sampleSize      - the sample size (i.e. 8 = 8-bit, 16 = 16-bit)
  63.     sampleRate      - the sampling rate (in samples/second)
  64.     sampleCount     - the number of audio samples in the handle
  65.     buffer          - always returns 0
  66.     reserved        - always returns 0  
  67.  
  68. The numFrames parameter returns the number of frames of audio data in the handle, and the dataOffset parameter returns the byte offset of the first audio sample in the handle.
  69.  
  70. Errors:
  71.         siInvalidCompression    - compression type not supported
  72.     badFormat               - file does not contain valid 'snd ' data
  73.     nilHandleErr             - a nil handle was passed
  74.  
  75. pascal OSErr GetCompressionName(OSType compressionType, Str255 compressionName)
  76.  
  77. GetCompressionName returns a string describing the given compression format in a string that can be displayed to the user. The compressionType parameter specifies the compression format, and the name is returned in compressionName. This string can be used in pop-up menus and other user interface elements to allow the user to select a compression format.
  78.  
  79. Errors:
  80.     memFullErr              - not enough memory to load name
  81.     siInvalidCompression    - compression type not supported
  82.     resNotFound             - compression name not available
  83.  
  84. Converting Sounds
  85.  
  86. An architecture has been added to Sound Manager 3.2 to allow you to easily convert between sound formats. Some of the operations that can be performed are compression, decompression, channel conversion, sample rate conversion and sample format conversion.
  87.  
  88. A conversion session is begun by calling SoundConverterOpen, to which you pass the format of the sound to be converted and the resulting output format. A SoundConverter identifier is returned that must be passed to all further routines in this session. SoundConverterClose is used to close the session.
  89.  
  90. SoundConverterGetBufferSizes allows you to determine input and output buffer sizes based on a target buffer size. This lets you create buffers to fit the conversion established with SoundConverterOpen.
  91.  
  92. Converting a sound is a three-step process. First, you call SoundConverterBeginConversion to initiate the conversion and reset the SoundConverter to default settings. Then SoundConverterConvertBuffer is called one or more times to convert sequential buffers of the input data to the output format. Finally, when all input data has been converted, SoundConverterEndConversion flushes out any data left in the converter.
  93.  
  94. pascal OSErr SoundConverterOpen(const SoundComponentData *inputFormat,
  95.                      const SoundComponentData *outputFormat, SoundConverter *sc)
  96.  
  97. SoundConverterOpen sets up the conversion session and returns a SoundConverter identifier to be passed to all further routines. The inputFormat parameter specifies the format of the sound data to be converted using a SoundComponentData structure. The following fields must be set up to describe the sound correctly:
  98.  
  99.     flags           - set to 0
  100.     format          - the sound format (i.e. 'raw ', 'twos', 'MAC3', etc.)
  101.     numChannels     - the number of channels  (i.e. 1 = mono, 2 = stereo)
  102.     sampleSize      - the sample size (i.e. 8 = 8-bit, 16 = 16-bit)
  103.     sampleRate      - the sampling rate (in samples/second)
  104.     sampleCount     - set to 0
  105.     buffer          - set to 0
  106.     reserved        - set to 0  
  107.  
  108. The outputFormat parameter specifies the output format, and must be passed fields similar to inputFormat. Output fields that are different from input fields will cause a conversion. For example, if the input sound format is 'raw ' and the output format is 'MAC3', the data resulting from the conversion will be compressed with MACE 3:1. This allows any combination of compression, decompression, channel conversion, sample size conversion and sampling rate conversion. A SoundConverter identifier is returned to manage the session, which must be passed to all further routines.
  109.  
  110. This routine cannot be called at interrupt time.
  111.  
  112. Errors:
  113.     memFullErr              - not enough memory
  114.     siInvalidCompression    - compression type not supported
  115.     siInvalidSampleSize     - sample size not supported
  116.  
  117. pascal OSErr SoundConverterClose(SoundConverter sc)
  118.  
  119. SoundConverterClose terminates the session and frees up all memory and services associated with this session.
  120.  
  121. This routine cannot be called at interrupt time.
  122.  
  123. Errors:
  124.     none
  125.  
  126. pascal OSErr SoundConverterGetBufferSizes(SoundConverter sc, unsigned long targetBytes,
  127.                      unsigned long *inputFrames, unsigned long *inputBytes,
  128.                      unsigned long *outputBytes)
  129.  
  130. SoundConverterGetBufferSizes is used to determine the input and output buffer sizes for a given target size. This is so you can make sure your buffers will fit the conversion parameters established with SoundConverterOpen.
  131.  
  132. The targetBytes parameter is the approximate number of bytes you would like both your input and output buffers to be. The inputFrames and inputBytes parameters return the actual size you should make your input buffer, in frames and bytes respectively. The outputBytes parameter returns the size in bytes for your output buffer.
  133.  
  134. Note: The returned input and output buffer sizes CAN be larger than your target size settings. This is because they are rounded up depending on the format, but they will be very close to the target settings. Also note that the input and output sizes may be very different, depending on the input and output formats given in SoundConverterOpen. The sizes are calculated assuming you will convert all data in the input buffer to the output buffer.
  135.  
  136. This routine cannot be called at interrupt time.
  137.  
  138. Errors:
  139.     notEnoughBufferSpace    - input bytes target too small
  140.     
  141.  
  142. pascal OSErr SoundConverterBeginConversion(SoundConverter sc)
  143.  
  144. SoundConverterBeginConversion starts a conversion. All state information is reset to default values in preparation for a new input buffer.
  145.  
  146. This routine can be called at interrupt time.
  147.  
  148. Errors:
  149.     none
  150.  
  151. pascal OSErr SoundConverterConvertBuffer(SoundConverter sc, const void *inputPtr,
  152.                      unsigned long inputFrames, void *outputPtr,
  153.                      unsigned long *outputFrames, unsigned long *outputBytes)
  154.  
  155. SoundConverterConvertBuffer converts a buffer of data from the input format to the output format. The inputPtr parameter points to the input data, and inputFrames gives the number of frames in that buffer. The outputPtr parameter specifies where the output data should be placed. The output Frames and outputBytes parameters return the number of frames and bytes placed in the output buffer respectively.
  156.  
  157. This routine will consume all the data in the input buffer, but, depending on the complexity of the conversion, not all the converted data may be put in the output buffer right away. The SoundConverterEndConversion routine is used to flush out all this remaining data before a conversion session is closed.
  158.  
  159. If you are using this routine in conjunction with SoundConverterGetBufferSizes, it is very important that you do not pass in a value in inputFrames larger than the frames value returned by SoundConverterGetBufferSizes, or you will overflow your output buffer. The SoundConverterConvertBuffer calls converts ALL the input data!
  160.  
  161. This routine can be called at interrupt time.
  162.  
  163. Errors:
  164.     none
  165.  
  166. pascal OSErr SoundConverterEndConversion(SoundConverter sc, void *outputPtr,
  167.                      unsigned long *outputFrames, unsigned long *outputBytes)
  168.  
  169. SoundConverterEndConversion ends a conversion. Any data remaining in the converters is flushed out and returned here.
  170.  
  171. This routine can be called at interrupt time.
  172.  
  173. Errors:
  174.     none
  175.  
  176. Conversion Example
  177.  
  178. The following is an example of how to use the sound conversion architecture to convert a buffer of silence to IMA 4:1, changing the sampling rate in the process.
  179.  
  180. enum {
  181.     kTargetBytes = 20 * 1024
  182. };
  183.  
  184. void main(void)
  185. {
  186.     SoundConverter      sc;
  187.     SoundComponentData  inputFormat, outputFormat;
  188.     unsigned long       inputFrames, inputBytes;
  189.     unsigned long       outputFrames, outputBytes;
  190.     Ptr                 inputPtr, outputPtr;
  191.     OSErr               err;
  192.     
  193.     inputFormat.flags = 0;
  194.     inputFormat.format = kOffsetBinary;
  195.     inputFormat.numChannels = 1;
  196.     inputFormat.sampleSize = 8;
  197.     inputFormat.sampleRate = rate22050hz;
  198.     inputFormat.sampleCount = 0;
  199.     inputFormat.buffer = nil;
  200.     inputFormat.reserved = 0;
  201.  
  202.     outputFormat.flags = 0;
  203.     outputFormat.format = 'ima4';
  204.     outputFormat.numChannels = 1;
  205.     outputFormat.sampleSize = 16;
  206.     outputFormat.sampleRate = rate44100hz;
  207.     outputFormat.sampleCount = 0;
  208.     outputFormat.buffer = nil;
  209.     outputFormat.reserved = 0;
  210.  
  211.     err = SoundConverterOpen(&inputFormat, &outputFormat, &sc);
  212.     if (err != noErr)
  213.         DebugStr("\pOpen failed");
  214.  
  215.     err = SoundConverterGetBufferSizes(sc, kTargetBytes,
  216.                     &inputFrames, &inputBytes, &outputBytes);
  217.     if (err != noErr)
  218.         DebugStr("\pGetBufferSizes failed");
  219.  
  220.     inputPtr = NewPtrClear(inputBytes);
  221.     outputPtr = NewPtrClear(outputBytes);
  222.  
  223.     // fill input buffer with 8-bit silence
  224.     {
  225.         int     i;
  226.         Ptr     dp = inputPtr;
  227.  
  228.         for (i = 0; i < inputBytes; i++)
  229.             *dp++ = 0x80;
  230.     }
  231.  
  232.     err = SoundConverterBeginConversion(sc);
  233.     if (err != noErr)
  234.         DebugStr("\pBegin Conversion failed");
  235.  
  236.     err = SoundConverterConvertBuffer(sc, inputPtr, inputFrames,
  237.                     outputPtr, &outputFrames, &outputBytes);
  238.     if (err != noErr)
  239.         DebugStr("\pConversion failed");
  240.  
  241.     err = SoundConverterEndConversion(sc,
  242.                     outputPtr,&outputFrames, &outputBytes);
  243.     if (err != noErr)
  244.         DebugStr("\pEnd Conversion failed");
  245.  
  246.     err = SoundConverterClose(sc);
  247.     if (err != noErr)
  248.         DebugStr("\pClose failed");
  249. }
  250.  
  251.  
  252. Bugs Fixed/New Features
  253.  
  254. Sound Output
  255.  
  256. New version of InstallMoveHHiPatch that will install on PowerMacs when the old Memory Manager is running. On PowerMacs with our new native PowerPC sound components we use more than 3k of the stack. The MoveHHi() in the new ROMs will only preserve 3k so we have to patch it to preserve more stack space.
  257.  
  258. Use a nil sound output component reference to specify the default device when calling Get/SetSoundOutputInfo().
  259.  
  260. Deal with left over samples during compression better by preserving them across calls to PlaySourceBuffer(). This allows sequential calls to a compressor with non-packet multiple buffer sizes to seam together without clicks.
  261.  
  262. Fixed SetSource() in the format converter so it does not ask the source for 8-bit twos-complement data, which no other sound component supports. This fixes problems when the format converter is installed after the mixer and is asked to output 8-bit twos.
  263.  
  264. In the sample rate converter the samplesToSkip field now stores the amount to skip into a new buffer. The byteOffset field is updated to this value when a new buffer is received. This fixes a problem playing scales with the freqDuration command when a new buffer is played before the old buffer has reached the end.
  265.  
  266. The gestaltSoundAttr proc being installed needs to avoid using unknown CPUs or re-cycled machine types.
  267.  
  268. Sound Input
  269.  
  270. Multiply bytesPerSample by 8 to get sampleSize for sound header. Fixes bug in SetupSndHeader with arbitrary compression formats.
  271.  
  272. Hardware
  273.  
  274. In the 8100 PowerMac series, fixed siHardwareMute support. It was reporting the hardware as muted in some cases when the sound could be heard.
  275.  
  276. Added speaker and headphone muting into the preferences. This allows for the user to specify the speaker is no muted when using external speakers or headphones, and the next time the machine is started the user's preference is restore. Previously it would default to always muting the speaker if something was inserted into the headphone jack.
  277.  
  278. Fixed the siHardwareBusy selector in the 8500 series.
  279.  
  280. Preserve register A0 within DetermineInputSource() when calling GetInitialPreferences().
  281.  
  282. Interfaces
  283.  
  284. SndSoundManagerVersion(), SPBVersion(), and MACEVersion() should all return a NumVersion. A recent version of the interfaces were changed to return an unsigned long, but this fails with creating native PowerPC code.
  285.  
  286. A new version of SoundLib has been released to include all of the new Sound Manager 3.2 API.
  287.